#ifndef DSPSIMULATOR_DSPINSTINFO_H
#define DSPSIMULATOR_DSPINSTINFO_H

#include <bitset>
#include "simulator/instruction/instInfo.h"

/**
 * DspInstInfo类为InstInfo的派生类，表示从dsp内存中取出的一条指令的指令数据
 */
class DspInstInfo : public InstInfo {
private:
    /**
     * 0 Loads are nonprotected (NOPs must be explicit).
     * 1 Loads are protected (4 NOP cycles added after every LD instruction)
     */
    bool m_PROT;

    /**
    *  0 Instructions use low register set for m_data source and destination.
    *  1 Instructions use high register set for m_data source and destination
    */
    bool m_RS;

    /**
     * Defines primary and secondary m_data size
     */
    std::bitset<3> m_DSZ;

    /**
     * 0 Compact instructions in the S unit are not decoded as branches
     * 1 Compact Instructions in the S unit are decoded as branches.
     */
    bool m_BR;

    /**
     * 0 Compact instructions do not saturate.
     * 1 Compact instructions saturate.
     */
    bool m_SAT;

    /**
     * parallel execution; 0 = next instruction is not executed in parallel, 1 = next instruction is executed in parallel
     */
    bool m_p;

    bool m_isStandardPacket;
public:
    explicit DspInstInfo(const std::vector<u8> &bits, u64 address, bool isStandardPacket = true, bool PROT = false,
                         bool RS = false, const std::bitset<3> &DSZ = 0, bool BR = false, bool SAT = false,
                         bool p = false) :
            InstInfo(bits, address), m_PROT(PROT), m_RS(RS), m_DSZ(DSZ), m_BR(BR), m_SAT(SAT), m_p(p),
            m_isStandardPacket(isStandardPacket) {};

    ~DspInstInfo() override = default;

    bool getPROT() const { return m_PROT; };

    bool getRS() const { return m_RS; };

    std::bitset<3> getDSZ() const { return m_DSZ; };

    bool getBR() const { return m_BR; };

    bool getSAT() const { return m_SAT; };

    bool getP() const { return m_p; };

    /**
     * 判断当前的指令数据是否为Standard指令
     * @return 如果为Standard指令，返回true，否则返回false
     */
    bool isStandardInstruction() const {
        return m_bits.size() == 4;
    }

    /**
    * 判断当前的指令数据在否为Standard指令包中
    * @return 如果在Standard指令包中，返回true，否则返回false
     */
    bool isStandardPacket() const {
        return m_isStandardPacket;
    }
};

#endif //DSPSIMULATOR_DSPINSTINFO_H
